package com.mlh.web;

import com.mlh.datavalid.entity.Monster;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

@Controller
@Scope(value = "prototype")
public class MonsterHandler {
    //显示添加 monster 的界面
    //当我们向map添加的数据时，会默认存放到request域
    @RequestMapping(value = "/addMonsterUI")
    public String addMonsterUI(Map<String, Object> map) {
    /**老韩解读:
     1. 这里的表单，我们使用 springMVC 的标签来完成
     2. SpringMVC 表单标签在显示之前必须在 request 中有一个 bean, 该 bean的属性和表单标签的字段要对应!
     request 中的 key 为: form 标签的 modelAttrite 属性值， 比如这里的monsters
     3. SpringMVC 的 form:form 标签的 action 属性值中的 /不代表 WEB 应用的根目录.
     4. <form:form action="monster" method="POST" modelAttribute="monster">
     // 这 里 需 要 给 request 增 加 一 个 monster ， 因为 jsp页面的modelAttribute="monster"需要
     //这时是 springMVC 的内部的检测机制 即使是一个空的也需要，否则报错.
    }
     */
        map.put("monster", new Monster());
        return "datavalid/monster_addUI";
    }
    // 1. springmvc可以将提交的数据，按照参数名和对象的属性名匹配
    // 2.直接封装到对象中
    // 3. @Valid Monster monster :表示对monster接收的数据进行校验 如果没有该注解 就不能进行验证
    // 4. Errors errors 表示如果校验出现错误，将校验的错误信息保存errors
    // 5. Map<String,0bject> map 表示如果校验出现错误，将校验的错误信息保存map同时保有monster对象
    //6.校验发生的时机:在springmvc底层， 反射调用目标方法时，会接收到http 清求的数据，然后根据注解来进行验证
    // 在验证过程中，如果出现了错误，就把错误信息填充errors和map
    @RequestMapping(value = "/save")
    public String save(@Valid Monster monster, Errors errors,Map<String,Object>map) {
        System.out.println("----monster---" + monster);
        // 我们为了看到验证的情况,我们输出map和errors
        System.out.println("===== map ======");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            System.out.println("key= " + entry.getKey() + " value=" + entry.getValue());
        }
        System.out.println("===== errors ======");
        List<ObjectError> allErrors = errors.getAllErrors();
        if(errors.hasErrors()){
            for (ObjectError error : allErrors) {
                System.out.println("error=" + error);
            }
            return "datavalid/monster_addUI";
        }
            return "datavalid/success";
    }

    @InitBinder
    public void initBinder(WebDataBinder webDataBinder){
        // 1.方法上需要标注@InitBinder springmvc 底层会初始化WebDataBinder
        // 2.调用webDataBinder.setDisallowedFields( "name")表示取消指定属性的绑定
        // 即:当表单提交字段为name时，就不在把接收到的name值，填充到model数据monster的name属性
        // 3.机制: springmvc 在底层通过反射调用目标方法时，接收到http 请求的参数和值,使用反射+注解技术取消对指定属性的填充
        // 4. setDisallowedFields 支持可变参数，可以填写多个字段
        // 5.如果我们取消某个属性绑定,验证就没有意义了,应当把验证的注解去掉name,否则有可能会造成错误

        //webDataBinder.setDisallowedFields("name");
    }
}